/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include <proxygen/lib/http/codec/compress/QPACKStaticHeaderTable.h>

#include <folly/Indestructible.h>

#include <glog/logging.h>


namespace {

// Array of static header table entires pair
// Note: if updating this table (should never have to but whatever), update
// isHeaderNameInTableWithNonEmptyValue as well
//
// From https://github.com/quicwg/base-drafts/wiki/QPACK-Static-Table
const char* s_tableEntries[][2] = {
{ ":authority", "" },
{ ":path", "/" },
{ "age", "0" },
{ "content-disposition", "" },
{ "content-length", "0" },
{ "cookie", "" },
{ "date", "" },
{ "etag", "" },
{ "if-modified-since", "" },
{ "if-none-match", "" },
{ "last-modified", "" },
{ "link", "" },
{ "location", "" },
{ "referer", "" },
{ "set-cookie", "" },
{ ":method", "CONNECT" },
{ ":method", "DELETE" },
{ ":method", "GET" },
{ ":method", "HEAD" },
{ ":method", "OPTIONS" },
{ ":method", "POST" },
{ ":method", "PUT" },
{ ":scheme", "http" },
{ ":scheme", "https" },
{ ":status", "103" },
{ ":status", "200" },
{ ":status", "304" },
{ ":status", "404" },
{ ":status", "503" },
{ "accept", "*/*" },
{ "accept", "application/dns-message" },
{ "accept-encoding", "gzip, deflate, br" },
{ "accept-ranges", "bytes" },
{ "access-control-allow-headers", "cache-control" },
{ "access-control-allow-headers", "content-type" },
{ "access-control-allow-origin", "*" },
{ "cache-control", "max-age=0" },
{ "cache-control", "max-age=2592000" },
{ "cache-control", "max-age=604800" },
{ "cache-control", "no-cache" },
{ "cache-control", "no-store" },
{ "cache-control", "public, max-age=31536000" },
{ "content-encoding", "br" },
{ "content-encoding", "gzip" },
{ "content-type", "application/dns-message" },
{ "content-type", "application/javascript" },
{ "content-type", "application/json" },
{ "content-type", "application/x-www-form-urlencoded" },
{ "content-type", "image/gif" },
{ "content-type", "image/jpeg" },
{ "content-type", "image/png" },
{ "content-type", "text/css" },
{ "content-type", "text/html; charset=utf-8" },
{ "content-type", "text/plain" },
{ "content-type", "text/plain;charset=utf-8" },
{ "range", "bytes=0-" },
{ "strict-transport-security", "max-age=31536000" },
{ "strict-transport-security", "max-age=31536000; includesubdomains" },
{ "strict-transport-security", "max-age=31536000; includesubdomains; preload" },
{ "vary", "accept-encoding" },
{ "vary", "origin" },
{ "x-content-type-options", "nosniff" },
{ "x-xss-protection", "1; mode=block" },
{ ":status", "100" },
{ ":status", "204" },
{ ":status", "206" },
{ ":status", "302" },
{ ":status", "400" },
{ ":status", "403" },
{ ":status", "421" },
{ ":status", "425" },
{ ":status", "500" },
{ "accept-language", "" },
{ "access-control-allow-credentials", "FALSE" },
{ "access-control-allow-credentials", "TRUE" },
{ "access-control-allow-headers", "*" },
{ "access-control-allow-methods", "get" },
{ "access-control-allow-methods", "get, post, options" },
{ "access-control-allow-methods", "options" },
{ "access-control-expose-headers", "content-length" },
{ "access-control-request-headers", "content-type" },
{ "access-control-request-method", "get" },
{ "access-control-request-method", "post" },
{ "alt-svc", "clear" },
{ "authorization", "" },
{ "content-security-policy",
  "script-src 'none'; object-src 'none'; base-uri 'none'" },
{ "early-data", "1" },
{ "expect-ct", "" },
{ "forwarded", "" },
{ "if-range", "" },
{ "origin", "" },
{ "purpose", "prefetch" },
{ "server", "" },
{ "timing-allow-origin", "*" },
{ "upgrade-insecure-requests", "1" },
{ "user-agent", "" },
{ "x-forwarded-for", "" },
{ "x-frame-options", "deny" },
{ "x-frame-options", "sameorigin" }
};

const int kEntriesSize = sizeof(s_tableEntries) / (2 * sizeof(const char*));
}

namespace proxygen {

/**
 * Not currently used for QPACK, because the table contains 28 common headers
 * with non-empty value.  To get the list run:
 *
 * cat HTTPCommonHeaders.txt  | tr '[:upper:]' '[:lower:]' | \
 * xargs -n 1 --replace=STR \
 *    grep -w STR codec/compress/QPACKStaticHeaderTable.cpp | \
 *  grep -v "\"\"" | cut -d\" -f 2 | sort | uniq | \
 *  tr '[:lower:]' '[:upper:]' | \
 * sed -e's/^/HTTP_HEADER_/g' -e's/-/_/g' -e's/:/COLON_/g'
 */
bool QPACKStaticHeaderTable::isHeaderCodeInTableWithNonEmptyValue(
    HTTPHeaderCode /*headerCode*/) {
  LOG(FATAL) << __func__ << " not supported for QPACK";
  return false;
}

const StaticHeaderTable& QPACKStaticHeaderTable::get() {
  static const folly::Indestructible<StaticHeaderTable> table(
    s_tableEntries, kEntriesSize);
  return *table;
}

}
